﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using PLCSharp.CoreModel.UserControls.ROI;

namespace PLCSharp.CoreModel.UserControls
{
    /// <summary>
    /// ImageEdit.xaml 的交互逻辑
    /// </summary>
    public partial class ImageEdit : UserControl
    {
        public ImageEdit()
        {
            InitializeComponent();
        }

        #region 缩放

        private double zoom = 1d;

        private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            //鼠标位置
            Point p = e.GetPosition(mainBox1);

            //bs 缩放系数 e.Delta 上滚120 & 下滚-120
            double bs = 1 + e.Delta * 0.001;

            //相对鼠标的移动量
            double offX = p.X - p.X * bs;
            double offY = p.Y - p.Y * bs;

            //变换矩阵
            var newMatrix = new Matrix(bs, 0, 0, bs, offX, offY);

            //
            matrix.Matrix = newMatrix * matrix.Matrix;
            zoom *= bs;
            rate.Text = zoom.ToString("P2");
        }

        #endregion 缩放

        #region 图片

        public WriteableBitmap ImageSource
        {
            get { return (WriteableBitmap)GetValue(ImageSourceProperty); }
            set { SetValue(ImageSourceProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ImageSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ImageSourceProperty =
            DependencyProperty.Register("ImageSource",
                typeof(WriteableBitmap),
                typeof(ImageEdit),
                new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, ImageSourceChangedCallback));

        private static void ImageSourceChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var u = d as ImageEdit;
            u.img1.Source = (WriteableBitmap)e.NewValue;
            u.matrix.Matrix = new Matrix(1, 0, 0, 1, 0, 0);
            u.zoom = 1d;
            u.rate.Text = u.zoom.ToString("P2");
        }

        #endregion 图片

        #region 拖动和画
        private DateTime _lastClickTime = DateTime.MinValue;
        private const int DoubleClickThreshold = 500; // 500毫秒内视为双击

        private bool isMouseLeftButtonDown = false;

        private Point previousMousePoint;
        private Point position;

        private void Img_MouseDown1(object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Released) return;
            isMouseLeftButtonDown = true;
            previousMousePoint = e.GetPosition(mainBox1);

            DateTime now = DateTime.Now;
            TimeSpan duration = now - _lastClickTime;
            if (duration.TotalMilliseconds <= DoubleClickThreshold)
            {

                matrix.Matrix = new Matrix(1, 0, 0, 1, 0, 0);
                zoom = 1d;
                rate.Text = zoom.ToString("P2");
                _lastClickTime = DateTime.MinValue; // 重置时间，避免连续触发
            }
            else
            {
                _lastClickTime = now; // 更新最后点击时间
            }
        }

        private void Img_MouseUp1(object sender, MouseButtonEventArgs e)
        {
            if (isMouseLeftButtonDown && drawing)
            {
                if (mainBox1.Children.Contains(ROItemp))
                    mainBox1.Children.Remove(ROItemp);
                switch (ROIType)
                {
                    case ROIType.Rect:
                        {
                            RectROI roi = new();
                            roi.roi.Width = ROItemp.RectWidth;
                            roi.roi.Height = ROItemp.RectHeight;

                            roi.RectWidth = ROItemp.RectWidth;
                            roi.RectHeight = ROItemp.RectHeight;

                            var top = (int)Canvas.GetTop(ROItemp);
                            var left = (int)Canvas.GetLeft(ROItemp);

                            roi.CenterX = left + roi.RectWidth / 2;
                            roi.CenterY = top + roi.RectHeight / 2;
                            mainBox1.Children.Add(roi);
                            Canvas.SetTop(roi.roi, top);
                            Canvas.SetLeft(roi.roi, left);

                        }
                        break;

                    default:
                        break;
                }

                drawing = false;
            }
            isMouseLeftButtonDown = false;
        }

        public void Draw(FrameworkElement path)
        {

            mainBox1.Children.Add(path);
            Childrens.Add(path);
        }
        public void Draw(FrameworkElement path, int row, int column)
        {
            Canvas.SetTop(path, row);
            Canvas.SetLeft(path, column);
            mainBox1.Children.Add(path);
            Childrens.Add(path);
        }

        private readonly List<FrameworkElement> Childrens = [];

        public void Remove(string tag)
        {
            var paths = Childrens.Where(u => u.Tag.ToString() == tag);

            foreach (var p in paths)
            {
                if (mainBox1.Children.Contains(p))
                {
                    mainBox1.Children.Remove(p);
                }
            }

        }
        public void Clear()
        {

            mainBox1.Children.Clear();
        }

        public async Task<RectROI> DrawROIAsync()
        {

            ROIType = ROIType.Rect;
            drawing = true;
            while (drawing) { 
                await Task.Delay(100);
            }
            return ROItemp;

        }

        private void Img_MouseLeave1(object sender, MouseEventArgs e)
        {
            isMouseLeftButtonDown = false;
        }

        private readonly RectROI ROItemp = new();

        private void Img_MouseMove1(object sender, MouseEventArgs e)
        {
            position = e.GetPosition(mainBox1);
            mousex.Text = position.X.ToString("F0");
            mousey.Text = position.Y.ToString("F0");

            if (isMouseLeftButtonDown == false) return;

            if (drawing)
            {
                mainBox1.Children.Remove(ROItemp);
                var startX = Math.Min(position.X, previousMousePoint.X);
                var startY = Math.Min(position.Y, previousMousePoint.Y);
                var endX = Math.Max(position.X, previousMousePoint.X);
                var endY = Math.Max(position.Y, previousMousePoint.Y);
                double width = endX - startX;
                double height = endY - startY;

                if (width < 1 || height < 1) return;

                ROItemp.RectWidth = (int)width;
                ROItemp.RectHeight = (int)height;
                ROItemp.roi.Width = ROItemp.RectWidth;
                ROItemp.roi.Height = ROItemp.RectHeight;

                mainBox1.Children.Add(ROItemp);
                Canvas.SetTop(ROItemp, startY);
                Canvas.SetLeft(ROItemp, startX);

                return;
            }

            double offX = position.X - previousMousePoint.X;
            double offY = position.Y - previousMousePoint.Y;
            //变换矩阵
            var newMatrix = new Matrix(1, 0, 0, 1, offX, offY);
            matrix.Matrix = newMatrix * matrix.Matrix;
        }

        private bool drawing;

        private ROIType ROIType;

    }

    public enum ROIType
    {
        Rect = 0,
        Circle = 1,
    }
    #endregion
}